package me.yricky.cov_spectrum.ui.activity

import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.compose.animation.*
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import dev.chrisbanes.snapper.ExperimentalSnapperApi
import dev.chrisbanes.snapper.SnapOffsets
import dev.chrisbanes.snapper.SnapperFlingBehaviorDefaults
import dev.chrisbanes.snapper.rememberSnapperFlingBehavior
import kotlinx.coroutines.launch
import me.yricky.cov_spectrum.R
import me.yricky.cov_spectrum.model.beans.PangoLineageItem
import me.yricky.cov_spectrum.model.beans.QueryCase
import me.yricky.cov_spectrum.model.utils.webPageUrl
import me.yricky.cov_spectrum.ui.content.*
import me.yricky.cov_spectrum.ui.openByWebView
import me.yricky.cov_spectrum.ui.theme.*
import me.yricky.cov_spectrum.viewmodel.*

class MainActivity : ComponentActivity() {
    private val countryViewModel:CountryViewModel by viewModels()
    private val pangoLineageViewModel:PangoLineageViewModel by viewModels()
    private val collectionViewModel:CollectionViewModel by viewModels()
    private val queryViewModel:CountQueryViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            CovspectrumTheme {
                val primaryColor = MaterialTheme.colors.primary
                LaunchedEffect(primaryColor){
                    window.statusBarColor = primaryColor.toArgb()
                }
                var currPageIndex by rememberSaveable {
                    mutableStateOf(2)
                }
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE){
                        HorizontalPage(currPageIndex){currPageIndex = it}
                    }else{
                        VerticalPage(currPageIndex){currPageIndex = it}
                    }
                }
            }
        }
    }

    @Composable
    fun VerticalPage(selectedPage:Int,onPageChange:(Int)->Unit){
        Column {
            PageFrame(currPageIndex = selectedPage, modifier = Modifier.weight(1f))
            BottomNavigation(Modifier.wrapContentHeight()) {
                BottomNavigationItem(
                    selected = selectedPage == 2,
                    onClick = { onPageChange(2) },
                    icon = { Icon(painter = painterResource(id = R.drawable.ic_round_style_24), contentDescription = "") }
                )
                BottomNavigationItem(
                    selected = selectedPage == 1,
                    onClick = { onPageChange(1) },
                    icon = { Icon(painter = painterResource(id = R.drawable.ic_round_account_tree_24), contentDescription = "") }
                )
                BottomNavigationItem(
                    selected = selectedPage == 0,
                    onClick = { onPageChange(0) },
                    icon = { Icon(painter = painterResource(id = R.drawable.ic_round_account_circle_24), contentDescription = "") }
                )
            }
        }
    }

    @Composable
    fun HorizontalPage(selectedPage:Int,onPageChange:(Int)->Unit){
        Row(Modifier.fillMaxSize()) {
            NavigationRail {
                NavigationRailItem(
                    selected = selectedPage == 2,
                    onClick = { onPageChange(2) },
                    icon = { Icon(painter = painterResource(id = R.drawable.ic_round_style_24), contentDescription = "") }
                )
                NavigationRailItem(
                    selected = selectedPage == 1,
                    onClick = { onPageChange(1) },
                    icon = { Icon(painter = painterResource(id = R.drawable.ic_round_account_tree_24), contentDescription = "") }
                )
                Spacer(modifier = Modifier.weight(1f))
                NavigationRailItem(
                    selected = selectedPage == 0,
                    onClick = { onPageChange(0) },
                    icon = { Icon(painter = painterResource(id = R.drawable.ic_round_account_circle_24), contentDescription = "") }
                )
            }
            PageFrame(currPageIndex = selectedPage)
        }
    }

    @Composable
    fun PageFrame(
        modifier: Modifier = Modifier,
        currPageIndex:Int
    ){
        Crossfade(targetState = currPageIndex,modifier) {
            when(it){
                1 ->{
                    PangoTabContent()
                }
                2->{
                    CollectionTabContent()
                }
                0 ->{
                    UserPage(Modifier.fillMaxSize())
                }
            }
        }
    }

    @OptIn(ExperimentalSnapperApi::class)
    @Composable
    fun CollectionTabContent(modifier: Modifier = Modifier){
        val list by collectionViewModel.list.collectAsState()
        val pagerState = rememberSaveable(
            saver = LazyListState.Saver,
            key = "coll_tab_page"
        ) {
            LazyListState(0, 0)
        }
        val currIndex by remember {
            derivedStateOf { pagerState.firstVisibleItemIndex }
        }
        Column {
            val scope = rememberCoroutineScope()

            val scrollStates by remember {
                derivedStateOf {
                    list.map { LazyGridState(0,0) }
                }
            }
            val showCommonTitle by remember {
                derivedStateOf { list.isEmpty() || scrollStates.getOrNull(currIndex)?.firstVisibleItemIndex == 0 }
            }
            var showSide by remember {
                mutableStateOf(false)
            }
            TopBar(content ={
                IconButton(painter = painterResource(id = R.drawable.ic_round_menu_24)) {
                    showSide = !showSide
                }
                Text(text = if(!showCommonTitle)list.getOrNull(currIndex)?.title ?: "" else "Collections",
                    style = MaterialTheme.typography.h5, maxLines = 1)
            }) {
                IconButton(
                    painter = painterResource(id = R.drawable.ic_round_refresh_24),
                ){ collectionViewModel.reloadList() }
            }
            val loadingStatus by collectionViewModel.loadingStatus.collectAsState()
            loadingStatus.let {
                when (it) {
                    is LoadingStatus.Loading -> {
                        LoadingPage(modifier = Modifier.fillMaxSize())
                    }
                    is LoadingStatus.Error -> {
                        ErrorPage(e = it.e)
                    }
                    else -> {
                        Box {
                            LazyRow(
                                modifier = modifier,
                                flingBehavior = rememberSnapperFlingBehavior(
                                    lazyListState = pagerState,
                                    snapOffsetForItem = SnapOffsets.Start,
                                    decayAnimationSpec = rememberSplineBasedDecay(),
                                    springAnimationSpec = SnapperFlingBehaviorDefaults.SpringAnimationSpec,
                                    endContentPadding = 0.dp,
                                    snapIndex = { layoutInfo, startIndex, targetIndex ->
                                        targetIndex
                                            .coerceIn(startIndex - 1, startIndex + 1)
                                            .coerceIn(0, layoutInfo.totalItemsCount - 1)
                                    },
                                ),
                                state = pagerState
                            ) {
                                itemsIndexed(
                                    list,
                                    key = { _, item ->  item.id }
                                ){ index,item ->
                                    Box {
                                        CollectionItemPage(
                                            Modifier.fillParentMaxSize(),
                                            collectionItem = item,
                                            scrollStates[index],
                                            queryViewModel = queryViewModel,
                                        )
                                    }
                                }
                            }
                            this@Column.AnimatedVisibility(
                                visible = showSide,
                                enter = fadeIn(),
                                exit = fadeOut()
                            ) {
                                Spacer(
                                    modifier = Modifier
                                        .fillMaxSize()
                                        .alpha(0.2f)
                                        .background(MaterialTheme.colors.onBackground)
                                        .clickable { showSide = false }
                                )
                            }
                            Row(
                                modifier.background(MaterialTheme.colors.background,
                                    RoundedCornerShape(0.dp,16.dp,16.dp,0.dp)
                                )
                            ) {
                                AnimatedVisibility(visible = showSide) {
                                    LazyColumn(modifier = Modifier
                                        .fillMaxHeight()
                                        .widthIn(0.dp, 240.dp)){
                                        itemsIndexed(
                                            list,
                                            key = { _, item ->  item.id }
                                        ){ index,item ->
                                            Row(
                                                modifier = Modifier
                                                    .clickable {
                                                        scope.launch { pagerState.scrollToItem(index) }
                                                    }
                                                    .padding(4.dp)
                                                    .fillMaxWidth()
                                                    .height(40.dp),
                                                verticalAlignment = Alignment.CenterVertically
                                            ) {
                                                if(currIndex == index){
                                                    val color = MaterialTheme.colors.primary
                                                    Canvas(modifier = Modifier
                                                        .padding(16.dp)
                                                        .size(8.dp)){
                                                        drawCircle(color)
                                                    }
                                                }
                                                Text(text = item.title)
                                            }
                                        }
                                    }
                                }
                            }
                        }


                    }
                }

            }
        }
    }

    @Composable
    fun PangoTabContent(modifier: Modifier = Modifier){
        Column(modifier = modifier) {
            var filter by rememberSaveable(key = "pl_filter") {
                mutableStateOf("")
            }
            val origList by pangoLineageViewModel.viewList.collectAsState()
            val list by remember {
                derivedStateOf {
                    origList.filter {
                        val filterFullName = pangoLineageViewModel.getFullName(filter.uppercase())
                        val plFullName = pangoLineageViewModel.getFullName(it.pangoLineage())
                        it.pangoLineage().contains(filter,true) ||
                                plFullName.contains("${filterFullName}.") || plFullName == filterFullName
                    }
                }
            }
            TopBar(
                content = {
                    Text(text = "Pango lineage",style = MaterialTheme.typography.h5)
                },
                tailIcon = {
                    IconButton(
                        painter = painterResource(id = R.drawable.ic_round_refresh_24),
                    ){ pangoLineageViewModel.reloadList() }
                }
            )
            OutlinedTextField(
                value = filter,
                onValueChange = { filter = it },
                trailingIcon = { Text(text = "${list.size}") },
                label = { Text(text = "Filter") },
                modifier = Modifier
                    .padding(8.dp, 4.dp)
                    .fillMaxWidth()
            )
            val sortBy:PangoLineageViewModel.SortBy by pangoLineageViewModel.sortBy.collectAsState()
            Row(verticalAlignment = Alignment.CenterVertically){
                IconButton(
                    painter = painterResource(id = R.drawable.ic_round_numbers_24),
                    tint = if(sortBy is PangoLineageViewModel.SortBy.Default){
                        MaterialTheme.colors.secondary
                    }else{
                        MaterialTheme.colors.onSurface
                    }
                ){
                    pangoLineageViewModel.setSortBy(PangoLineageViewModel.SortBy.Default(sortBy.reversed))
                }
                IconButton(
                    painter = painterResource(id = R.drawable.ic_round_sort_by_alpha_24),
                    tint = if(sortBy is PangoLineageViewModel.SortBy.Name){
                        MaterialTheme.colors.secondary
                    }else{
                        MaterialTheme.colors.onSurface
                    }
                ){
                    pangoLineageViewModel.setSortBy(PangoLineageViewModel.SortBy.Name(sortBy.reversed))
                }
                IconButton(
                    painter = painterResource(id = R.drawable.ic_round_sort_24),
                    tint = if(sortBy is PangoLineageViewModel.SortBy.Count){
                        MaterialTheme.colors.secondary
                    }else{
                        MaterialTheme.colors.onSurface
                    }
                ){
                    pangoLineageViewModel.setSortBy(PangoLineageViewModel.SortBy.Count(sortBy.reversed))
                }
                FidoTest()
                Checkbox(
                    checked = sortBy.reversed,
                    onCheckedChange = {
                        pangoLineageViewModel.setSortBy(sortBy.reverse())
                    }
                )
                Text(text = "Reversed")
            }
            Box{
                var focusItem:PangoLineageItem? by remember {
                    mutableStateOf(null)
                }
                PangoLineageList(
                    Modifier
                        .fillMaxSize()
                        .padding(8.dp),list = list,{ pangoLineageViewModel.getFullName(it) }
                ){
                    focusItem = it
                }
                focusItem?.let{
                    Dialog(onDismissRequest = { focusItem = null }) {
                        Surface(shape = RoundedCornerShape(16.dp)) {
                            Column(Modifier.padding(16.dp)) {
                                var txt by remember {
                                    mutableStateOf("")
                                }
                                Text(text = "${it.pangoLineage()}*",Modifier.align(Alignment.CenterHorizontally))
                                QueryLineChart(
                                    Modifier.size(240.dp, 160.dp),
                                    queryCase = QueryCase(nextcladePangoLineage = "${it.pangoLineage()}*"),
                                    name = "${it.pangoLineage()}*",
                                    queryViewModel = queryViewModel
                                ){ ds,it ->
                                    txt = "${it.date},${it.count}"
                                }
                                Text(text = txt)
                                val context = LocalContext.current
                                val colors = MaterialTheme.colors
                                IconButton(
                                    modifier = Modifier.size(32.dp),
                                    painter = painterResource(id = R.drawable.ic_round_open_in_new_24)
                                ) {
                                    context.openByWebView(
                                        QueryCase(nextcladePangoLineage = "${it.pangoLineage()}*").webPageUrl.toString(),
                                        colors
                                    )
                                }
                            }
                        }
                    }
                }

                val loadingStatus by pangoLineageViewModel.loadingStatus.collectAsState()
                loadingStatus.let {
                    when (it) {
                        is LoadingStatus.Loading -> {
                            LoadingPage(modifier = Modifier.fillMaxSize())
                        }
                        is LoadingStatus.Error -> {
                            ErrorPage(e = it.e)
                        }
                        else -> {}
                    }
                }
            }
        }
    }
}

@Preview
@Composable
fun FidoTest(){
    val context = LocalContext.current
    val pm = context.packageManager
    val ar = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult(), onResult = {
        println(it.data?.extras?.toString())
    })
    Button(onClick = {
        val intent = Intent("org.fidoalliance.intent.FIDO_OPERATION").apply {
            type = "application/fido.uaf_client+json"
            addCategory("android.intent.category.DEFAULT")
            val data = Bundle()
            data.putString("message", "{\"uafProtocolMessage\":\"[{\\\"header\\\":{\\\"upv\\\":{\\\"major\\\":1,\\\"minor\\\":0},\\\"op\\\":\\\"Auth\\\",\\\"appID\\\":\\\"https:\\/\\/m1.cmbc.com.cn:8003\\/CMBC_MBServer\\/scripts\\/fidoServer\\/facets.uaf\\\",\\\"serverData\\\":\\\"6nrCpvfPyNJkX8eHW87VUG0XPUuiLNbsfTytspGOk56_5tJ03N4EfxZrJ8rCTXMO6Ua0eQmIWMFP7c7McT7DCy17dnNO6rGsJTAlSkQ7MkT5rL0G_mxgwatwngfvoPPEEnfKH3YXGwfwDYLDNCxTR9H_VFej\\\"},\\\"challenge\\\":\\\"zZD296KOAjotrt0V3yWSBHO8IoVHjmX206dUc-l17ks\\\",\\\"policy\\\":{\\\"accepted\\\":[[{\\\"aaid\\\":[\\\"001B#0001\\\"],\\\"keyIDs\\\":[\\\"Dgvm9n-kemIlH-2aDcG3HVRwFtqSaQ_7UkLYC3_Z_yU\\\"]}]]}}]\"}")
            data.putString("UAFIntentType", "DISCOVER")
            data.putString("channelBindings", "")

            putExtras(data)
        }
        ar.launch(intent)

    }) {

    }

}